﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Text.RegularExpressions;
using DienLib.ReportLib;

namespace DienVu
{
    class ButtonEvent
    {
        public static void AddEvent_ClickDragDrop_BasicButton(Button button, string reportName, Configuration config, Configuration.Paths FILE_Path)
        {
            ButtonEvent but = new ButtonEvent(button, reportName, config, FILE_Path);
        }

        DienLib.ReportLib.Configuration config;
        Configuration.Paths FILE_Path; string reportName;
        int found;

        /// <summary>
        /// Any side effect ? Why when object dipose already (local var) but still can callback ? mean not realease because still have reference.
        /// So How to clean resource in this case ? Must -= allright ? or garbage collector will do the job.
        /// </summary>
        private ButtonEvent(Button button, string reportName, DienLib.ReportLib.Configuration config, Configuration.Paths FILE_Path)
        {
            this.config = config; this.FILE_Path = FILE_Path; this.reportName = reportName;
            button.AllowDrop = true;
            button.Click += new System.Windows.RoutedEventHandler(button_Click);
            button.DragEnter += new DragEventHandler(button_DragEnter);
            button.DragOver += new DragEventHandler(button_DragOver);
            button.Drop += new DragEventHandler(button_Drop);
        }

        #region button_Event
        private void button_Click(object sender, RoutedEventArgs e)
        {
            string strFILE_Path = config[FILE_Path];
            if (!string.IsNullOrEmpty(strFILE_Path))
                if (System.IO.File.Exists(strFILE_Path))
                {   // Khong trong
                    System.Diagnostics.Process.Start(strFILE_Path); return;
                }

            // NULL OR EMPTY OR NOT EXIST
            DienLib.PopUp.PopUpOK.ShowDialog(string.Format("No {0}, Please Drag & Drop your {0} to this Button !", reportName));
        }

        private void button_DragEnter(object sender, DragEventArgs e)
        {
            e.Handled = true;
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (files == null) { found = 0; return; }

            // If FOLDER or XLS FILE => ALLOW. IF FOLDER then after DROP will search for XLS FILE INSIDE
            found = 0; Regex regex = new Regex(config.GetPathPattern(FILE_Path)); // Use Regex Instance to increase Speed
            foreach (string file in files)
            {   // Co dinh dang giong voi Daily Report
                if (regex.IsMatch(System.IO.Path.GetFileName(file).ToLower())) found++;
            }
        }

        private void button_DragOver(object sender, DragEventArgs e)
        {
            e.Handled = true;
            if (found > 0) e.Effects = DragDropEffects.Copy;
            else e.Effects = DragDropEffects.None;
            e.Handled = true; // Any time you modify e.Effects in a drag event handler in WPF, you need to set e.Handled = true. Otherwise the default handlers will overwrite the value you set
        }

        private void button_Drop(object sender, DragEventArgs e)
        {
            e.Handled = true; // Avoid ParentForm.Drop do this again.
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (files == null) return;

            // If FOLDER or XLS FILE => ALLOW. IF FOLDER then after DROP will search for XLS FILE INSIDE
            List<int> foundList = new List<int>();
            Regex regex = new Regex(config.GetPathPattern(FILE_Path)); // Use Regex Instance to increase Speed
            for (int i = 0; i < files.Length; i++)
            {
                //string ext = System.IO.Path.GetExtension(file);
                //if (string.IsNullOrEmpty(ext)) { e.Effects = DragDropEffects.None; return; } /// Truong hop FILE trang hay FOLDER khong co duoi gi thi chua SUPPORT ?

                // Co dinh dang giong voi Daily Report
                if (regex.IsMatch(System.IO.Path.GetFileName(files[i]).ToLower())) foundList.Add(i);
            }

            if (foundList.Count > 1)
            { // Duplicate : POP UP WHICH ONE ?
                System.Windows.Forms.MessageBox.Show("IMPLEMENT DUPLICATE POP UP LATER");
            }
            else if (foundList.Count == 1)
            { // Only one : CODE FOR THIS FILE
                System.IO.FileInfo file = new System.IO.FileInfo(files[foundList.First()]);
                DienLib.PopUp.PopUpOK.ShowDialog(string.Format("Got this File : \"{0}\" !", file.Name), reportName.ToUpper() + " FOUND !");
                try { ChangeNewPath(file); }
                catch (Exception ex) { DienLib.PopUp.PopUpOK.ShowDialog(ex.Message, "CHANGE NEW PATH FAIL"); }
            }
            else
            { // Not found
                //System.Windows.Forms.MessageBox.Show(string.Format("Not a {0} !", reportName));
                // Should not pop-up this otherwise when drag very very fast it will come here.
            }
        }

        private void ChangeNewPath(System.IO.FileInfo file)
        {
            // CHECK FOLDER PATH
            string strFOLDER_Path = config[Configuration.EnumFolderPaths(FILE_Path)];
            if (!System.IO.Directory.Exists(strFOLDER_Path))
            {   // FOLDER not exist, create new
                DienLib.PopUp.PopUpResult res = DienLib.PopUp.PopUpOKCancel.ShowDialog(string.Format("No {0} FOLDER, create new ?", reportName), reportName.ToUpper() + " FOLDER NOT FOUND");
                if (res == DienLib.PopUp.PopUpResult.CANCEL) return;
                else System.IO.Directory.CreateDirectory(strFOLDER_Path);
            }

            // CHECK FILE PATH
            string strFILE_Path = config[FILE_Path];
            if (strFILE_Path == file.FullName) return; // Re-register same file. Nothing happen !

            // CREATE NEW FILE PATH FOR COPY
            string dest = System.IO.Path.Combine(strFOLDER_Path, file.Name);
            if (dest == file.FullName) goto _LABEL_SETPATH; // Same source & dest but not register name -> Just register, no copy.

            // CHECK IF FILE PATH EXIST
            if (System.IO.File.Exists(strFILE_Path))
            {   // Have Current File
                DienLib.PopUp.PopUpResult res = DienLib.PopUp.PopUpConfirmReplace.ShowDialog(new System.IO.FileInfo(strFILE_Path), file,
                    string.Format("Will Copy & Replace OLD {0} with the File you just dragged in : ", reportName) +
                    string.Format("\"{0}\"", file.Name), "CHANGE NEW " + reportName.ToUpper()); // More code show Thumbnail
                if (res == DienLib.PopUp.PopUpResult.CANCEL) return;
            }
            
            // CHECK IF FILE PATH FOR COPY EXIST : YES = DUPLICATE
            if (System.IO.File.Exists(dest))
            {   // Same file name
                DienLib.PopUp.PopUpResult res = DienLib.PopUp.PopUpConfirmReplace.ShowDialog(new System.IO.FileInfo(dest), file,
                    string.Format("OOOOPPPP ! Man, please check {0} FOLDER. The file with same name already exist : ", reportName) +
                    string.Format("\"{0}\"", file.Name), "CONFIRM REPLACE DUPLICATE FILE NAME !!!"); // More code show Thumbnail
                if (res == DienLib.PopUp.PopUpResult.CANCEL) return;
            }

            // FILE current khong ton tai (hoac ton tai nhung confirm replace) | FILE copy toi khong trung (hoac trung nhung confirm replace)
            try { file.CopyTo(dest, true); }// Copy & Overwrite
            catch (Exception ex) { MessageBox.Show(ex.Message, "COPY FILE FAIL"); }

        _LABEL_SETPATH:
            config[FILE_Path] = dest;
        }
        #endregion
    }
}
